import xmpp
import re

from commands import CommandParser

class FeedBot(object):
    _client = None

    def __init__(self, user, pwd, server = 'talk.google.com', port = 5223, debug = []):
        jid = xmpp.JID(user)
        self._client = xmpp.Client(jid.getDomain(), debug = debug)
        if not self._client.connect((server, port)):
            raise ConnectError
        if not self._client.auth(jid.getNode(), pwd):
            raise AuthError

        self._client.RegisterHandler("message", self.__messageHandler)
        self._client.RegisterHandler("presence", self.__presenceHandler)
        self._client.sendInitPresence()
        self._client.send(xmpp.Presence(status = 'Avaliable'))

    def __messageHandler(self, client, message):
        text = message.getBody()
        user = message.getFrom()

        if not text or not text.strip(): return
        text = text.encode('utf-8', 'ignore')
        messages = re.split(r"\s+", text)
        cmd, feed_url, keyword = messages[0], '', ''
        if len(messages) >= 2:
            feed_url = messages[1]
        if len(messages) >= 3:
            keyword = messages[2:]
        try:
            cmdParser = CommandParser(user, cmd, feed_url, keyword)
            self.send(user, cmdParser.parser()) 
        except Exception, e:
            print 'ERROR - %s' % e
            self.send(user, e)

    def __presenceHandler(self, client, presence):
        type = presence.getType()
        user = presence.getFrom().getStripped()
        roster = self._client.getRoster()

        if type == 'subscribe':
            roster.Authorize(user)
        elif type == 'unsubscribe':
            roster.Unauthorize(user)

    def send(self, user, message):
        self._client.send(xmpp.Message(user, message))

    def _start(self):
        try:
            self._client.Process(1)
        except KeyboardInterrupt:
            return False
        return True

    def running(self):
        while self._start():
            pass

class ConnectError(Exception):
    def __str__(self):
        return "Error - FeedBot not connected."

class AuthError(Exception):
    def __str__(self):
        return "Error - FeedBot authentication failed."

if __name__ == "__main__":
    bot = FeedBot('myfeedbot@gmail.com', 'myfeedbotdemo')
    bot.running()
